package bingfa

import "fmt"

//使用全局变量加锁来解决goroutine问题并不完美
//主线程在等待所有的goroutine全部完成的时间很难确定，我们这里设置成10秒仅仅只是估算
//如果主线程休眠时间长了，会加长等待时间，如果等待时间短了，可能还有goroutine处于工作状态，这个时候会随主线程的退出而销毁
//通过全局变量加锁来实现通讯也不是很完美，这个时候就出现了一种新的数据结构-channel
//channel的基本介绍
//channel的本质其实就是一个数据队列
//数据是先进先出的
//线程安全，当有多个goroutine访问时不需要加锁，就是说channel本身就是线程安全的
//channel有类型的，一个string的channel只能存放string类型数据
//举例：
//var intChan chan int
//var mapChan chan map[int]string
//var perChan chan Person
//channel是引用数据类型，channel必须初始化才能写入数据，即make后才能使用，且不能向var ans []int直接声明后就可以使用了

func Test6(){
	//演示一下管道的使用
	//1,创建一个可以存放3个int类型的管道
	var intChan chan int
	intChan=make(chan int,3)
	//2,看看intChan是什么
	fmt.Printf("intChan的值=%v，intChan的地址=%p",intChan,&intChan)
	//3,向管道写入数据
	intChan<-10
	num:=211
	intChan<-num
	intChan<-1
	//intChan<-50
	//intChan<-100 注意，当我们给管道写入数据时不能超过其容量
	//4,看看管道的长度核cap（容量）
	fmt.Printf("channel len=%v cap=%v",len(intChan),cap(intChan))
	//5,从管道中读取数据
	var num2 int
	num2=<-intChan
	fmt.Println("num2=",num2)
	//6,注意，每取出管道中的一个数据管道中的长度就会少1，且该数据会在管道中清除,如果取出所有的数据了，再取出就会报错
	fmt.Printf("channel len=%v cap=%v",len(intChan),cap(intChan))
	num3:=<-intChan
	num4:=<-intChan
	fmt.Println(num3,num4)
}
//channel的使用注意事项
/*
channel只能存放指定的数据类型
在没有使用协程的情况下channle的数据满了后就不能再放入了
如果从channel取出数据后才可以继续放入
在没有使用协程的情况下，如果channel的数据读取完了后，再取就会报错，但是如果在使用协程的情况下就会阻塞
 */
